import { deepStrictEqual, strictEqual } from 'assert';
import { Mock } from 'lite-ts-mock';
import { TreePSD } from 'psd';

import { ConverterBase } from './base';
import { ProgressBar, Sprite, UITransform } from './cc';
import { ProgressBarConverter as Self } from './progress-bar';
import { ConverterFactoryBase, IConverter } from '../../contract';
import { enum_ } from '../../model';

describe('src/scene/service/converter/progress-bar.ts', () => {
    describe('.convert()', () => {
        it('ok', async () => {
            const mockTreePSD = new Mock<TreePSD>();
            const mockConverterFactory = new Mock<ConverterFactoryBase>();
            const self = new Self(null as any, mockConverterFactory.actual, null as any, mockTreePSD.actual);

            const node = {
                getComponent: (arg: any) => {
                    strictEqual(arg, UITransform);
                    return {
                        contentSize: {
                            y: 10
                        }
                    };
                }
            };
            Reflect.set(self, 'createNode', () => {
                return node;
            });

            const pb = {
                barSprite: null,
                progress: null as any,
                totalLength: null as any,
            } as ProgressBar;
            Reflect.set(self, 'appendComponent', (arg: any, arg1: any) => {
                strictEqual(arg, ProgressBar);
                strictEqual(arg1, node);
                return pb;
            });

            const mockBgTreePSD = new Mock<TreePSD>();
            const mockSpriteTreePSD = new Mock<TreePSD>();
            mockTreePSD.expectReturn(
                r => r.children(),
                [mockBgTreePSD.actual, mockSpriteTreePSD.actual]
            );

            mockBgTreePSD.expectReturn(
                r => r.get(enum_.Psd.name),
                'a.b'
            );

            mockBgTreePSD.expectReturn(
                r => r.get(enum_.Psd.width),
                50
            );

            Reflect.set(self, 'appendSprite', (arg: any, arg1: any) => {
                strictEqual(arg, mockBgTreePSD.actual);
                strictEqual(arg1, node)
            });

            mockSpriteTreePSD.expectReturn(
                r => r.get(enum_.Psd.name),
                'c'
            );

            const mockConverter = new Mock<IConverter>();
            mockConverterFactory.expectReturn(
                r => r.build(mockSpriteTreePSD.actual),
                mockConverter.actual
            );

            const getComponentCtorFuncAssets: Function[] = [Sprite, UITransform];
            ConverterBase.getCcPropFunc = (arg: any) => {
                const ctor = getComponentCtorFuncAssets.shift();
                strictEqual(arg, ctor?.name);
                return ctor;
            };

            const sprite = {
                name: null,
                parent: null,
                getComponent: (arg: any) => {
                    strictEqual(arg, Sprite);
                    return {
                        node: {
                            position: {
                                y: null
                            }
                        }
                    };
                }
            };
            mockConverter.expectReturn(
                r => r.convert(),
                sprite
            );

            Reflect.set(self, 'createVec3', (arg: any, arg1: any) => {
                strictEqual(arg, -25);
                strictEqual(arg1, 0);
                return 'vec';
            });

            const res = await self.convert();
            strictEqual(res, node);
            deepStrictEqual(pb, {
                progress: 0.5,
                totalLength: 50,
                barSprite: {
                    node: {
                        position: {
                            y: -5
                        }
                    }
                }
            });
            strictEqual(sprite.name, 'p-bar');
            strictEqual(sprite.parent, node);
        });
    });
});